using System.Collections.Generic;
using GameServer.ShootingGame.RenderableClasses;
using System.Drawing;
using GameServer.Common.Utils;
using System;
namespace GameServer.ShootingGame.WeaponsClasses.LaunchProfiles
{

    public enum LaunchProfiles
    {
        LINEAR_TRAJECTORY,//bullet
        ARC_TRAJECTORY,// grenade
        ADJUSTING_TRAJECTORY//guided, homing
    };

    public static class LaunchProfile
    {

        //public static const SIMPLE_BULLET : String = "com.shootingGame.weaponsClasses.ordinance.simplebullet";


        //Returns array of launched ordinance
        public static List<Ordinance> Launch(LaunchProfiles launchProfile, Weapon weapon, WeaponInfo weaponInfo, double targetX, double targetY)
        {
            List<Ordinance> ordinanceList = new List<Ordinance>(1);
            double ordinanceRotation;
            Ordinance ordinance = null;
            PointF ordSpawnPoint_Global = PointF.Empty;

            if (weaponInfo.ShotsFired())
            {
                switch (launchProfile)
                {
                    case LaunchProfiles.LINEAR_TRAJECTORY:
                        ordSpawnPoint_Global = weapon.NozzlePoint;
                        //ordinanceRotation = Player(weapon.attachedTo).facing;
                        ordinanceRotation = Math2.GetAngleOfElevationDegree(ordSpawnPoint_Global.X, ordSpawnPoint_Global.Y, targetX, targetY);
                        ordinance = weaponInfo.ordinanceSample.Clone();
                        ordinance.xPosition = ordSpawnPoint_Global.X;
                        ordinance.yPosition = ordSpawnPoint_Global.Y;
                        ordinance.source = ordSpawnPoint_Global;
                        ordinance.target = new PointF(Convert.ToSingle(targetX), Convert.ToSingle(targetY));
                        ordinance.Facing = ordinanceRotation;
                        ordinance.VelocityDirection = ordinanceRotation;
                        ordinance.Speed = weaponInfo.ordinanceSpeed;
                        ordinance.GamePlayManager = ordinance.owner.GamePlayManager;
                        ordinance.StartUpdate();
                        break;

                    case LaunchProfiles.ARC_TRAJECTORY:
                        //						ordSpawnPointF = weapon.model.localToGlobal(new PointF(weapon.model.nozzle.x, weapon.model.nozzle.y));
                        //						ordinanceRotation = Math2.getRelativeElevationAngleDegree(ordSpawnPointF.X, ordSpawnPointF.Y, targetX, targetY);
                        //						ordinance = new classRef(weapon.attachedTo, launchProfile, weaponInfo.damage, ordSpawnPointF.X, ordSpawnPointF.Y, targetX, targetY, ordinanceRotation, 1);
                        //						ordinanceList.push(ordinance);
                        break;
                    case LaunchProfiles.ADJUSTING_TRAJECTORY:
                        ordSpawnPoint_Global = weapon.NozzlePoint;
                        //ordinanceRotation = Player(weapon.attachedTo).facing;
                        ordinanceRotation = Math2.GetAngleOfElevationDegree(ordSpawnPoint_Global.X, ordSpawnPoint_Global.Y, targetX, targetY);
                        ordinance = weaponInfo.ordinanceSample.Clone();
                        ordinance.xPosition = ordSpawnPoint_Global.X;
                        ordinance.yPosition = ordSpawnPoint_Global.Y;
                        ordinance.source = ordSpawnPoint_Global;
                        ordinance.target = new PointF(Convert.ToSingle(targetX), Convert.ToSingle(targetY));
                        ordinance.Facing = ordinanceRotation;
                        ordinance.VelocityDirection = ordinanceRotation;
                        ordinance.Speed = weaponInfo.ordinanceSpeed;
                        ordinance.GamePlayManager = ordinance.owner.GamePlayManager;
                        ordinance.StartUpdate();
                        break;
                }
            }
            return ordinanceList;
        }

        public static void UpdateTrajectory(LaunchProfiles launchProfile, Ordinance ordinance, PointF sourcePointF, PointF targetPointF)
        {
            //INEVITABLE CHANGE MARKER
            //The following line(s) of code will need to be changed in future.
            //Reason: SCROLLING MAP and memory storage of non-rendered off-screen objects (essential server function).
            //var ordPosition_Local : PointF = GamePlayManager.instance.bulletHolder.localToGlobal(new PointF(ordinance.xPosition, ordinance.yPosition));
            WeaponInfo weaponInfo = ordinance.weaponInfo;
            if (launchProfile == LaunchProfiles.LINEAR_TRAJECTORY)
                return;
            if (launchProfile == LaunchProfiles.ARC_TRAJECTORY)
            {
                return;
            }
            if (launchProfile == LaunchProfiles.ADJUSTING_TRAJECTORY)
            {
                if (weaponInfo.TurningRate > 0)
                {

                    //var desiredFacing : Number = Math2.getAngleOfElevationDegree(ordPosition_Local.x, ordPosition_Local.y, targetPointF_Local.x, targetPointF_Local.y);
                    double desiredFacing = Math2.GetAngleOfElevationDegree(ordinance.xPosition, ordinance.yPosition, targetPointF.X, targetPointF.Y);
                    double deltaAngleRequired = Math2.GetChangeInAngle(desiredFacing, Math2.ConvertTo180DegreeAngle(ordinance.Facing));
                    double deltaAngle = 0;
                    if (Math.Abs(deltaAngleRequired) <= weaponInfo.TurningRate)
                        deltaAngle = deltaAngleRequired;
                    else
                    {
                        if (deltaAngleRequired > 0)
                            deltaAngle = weaponInfo.TurningRate;
                        else
                            if (deltaAngleRequired < 0)
                                deltaAngle = -weaponInfo.TurningRate;
                    }
                    ordinance.Facing += deltaAngle;
                    ordinance.VelocityDirection = ordinance.Facing;
                }
                return;
            }

        }
    }
}
